package com.jdcjk.project.navigation.view.gaode;

import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.AMapNaviView;
import com.amap.api.navi.AMapNaviViewOptions;
import com.amap.api.navi.enums.NaviType;
import com.amap.api.navi.model.AMapLaneInfo;
import com.amap.api.navi.model.AMapNaviCross;
import com.amap.api.navi.model.AMapNaviInfo;
import com.amap.api.navi.model.AMapNaviLocation;
import com.amap.api.navi.model.AMapNaviStaticInfo;
import com.amap.api.navi.model.AMapNaviTrafficFacilityInfo;
import com.amap.api.navi.model.AimLessModeCongestionInfo;
import com.amap.api.navi.model.AimLessModeStat;
import com.amap.api.navi.model.NaviInfo;
import com.amap.api.navi.model.NaviLatLng;
import com.amap.api.navi.view.NextTurnTipView;
import com.amap.api.navi.view.ZoomInIntersectionView;
import com.autonavi.tbt.NaviStaticInfo;
import com.autonavi.tbt.TrafficFacilityInfo;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechSynthesizer;
import com.iflytek.cloud.SynthesizerListener;
import com.jdcjk.Constant;
import com.jdcjk.R;
import com.jdcjk.base.view.BaseActivity;
import com.jdcjk.project.navigation.presenter.NavigationFindPresenter;
import com.jdcjk.util.GaoDeMapUtil;
import com.jdcjk.util.L;
import com.jdcjk.util.TimeUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2016/12/21 0021.
 * 寻车导航界面
 */

public class GDCarNavigationFindActivity extends BaseActivity<NavigationFindPresenter> implements View.OnClickListener {
    private final String TAG = GDCarNavigationFindActivity.class.getSimpleName();

    //顶栏返回Button
    private ImageButton back_button;
    //导航button
    private ImageButton startNavi_button;
    //实时路况button
    private ImageButton traffic_button;
    //导航声音button
    private FloatingActionButton naviVoice_button;
    //路口转向提示NextTurnTipView
    private NextTurnTipView nextTurnTipBiew;
    //方向textview
    private TextView direction_textView;
    //当前路径剩余距离textview
    private TextView pathRetainDistance_textView;
    //当前路线名称textview
    private TextView currentRoadName_textView;
    //总路线距离textview
    private TextView totalPathRetainDistance_textView;
    //总路线剩余时间textview
    private TextView pathRetainTime_textView;
    //导航方式选择
    private Spinner naviType_spinner;
    //导航方式标示（0为步行，1为骑行，2为驾车）
    private int naviType = 0;
    //地图控件
    private AMapNaviView aMapNavView = null;
    private AMapNavi aMapNavi = null;
    //个人位置信息
    private NaviLatLng personalNaviLatLng;
    //车辆位置信息
    private double latitude;
    private double longitude;
    //是否开始导航
    private boolean isNavi = false;
    //是否开启导航语音
    private boolean isOpenVoice = false;
    //是否开启交通图
    private boolean isOpenTraffic = true;
    //语音合成类SpeechSynthesizer
    private SpeechSynthesizer mTts;

    private AMapNaviViewOptions options;
    //路口放大图
    private ZoomInIntersectionView mZoomInIntersectionView;

    @Override
    public int getLayoutId() {
        return R.layout.activity_gaode_car_navi_find;
    }

    @Override
    public NavigationFindPresenter bindPresenter() {
        presenter = new NavigationFindPresenter(getBaseContext());
        return presenter;
    }

    @Override
    public void initContentView(Bundle savedInstanceState) {
        //获取地图控件引用
        //获取 AMapNaviView 实例
        aMapNavView = (AMapNaviView) findViewById(R.id.navi_view);
        aMapNavView.onCreate(savedInstanceState);
        initNavMap();
        back_button = (ImageButton) findViewById(R.id.back_btn);
        back_button.setOnClickListener(this);

        naviType_spinner = (Spinner) findViewById(R.id.navi_type_spinner);

        CarNaviTypeAdapter carNaviTypeAdapter = new CarNaviTypeAdapter(presenter.getNaviTypeData());
        //绑定到naviType_spinner
        naviType_spinner.setAdapter(carNaviTypeAdapter);
        naviType_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String naviTypeName = getResources().getString((Integer) presenter.getNaviTypeData().get(position).get("typeName"));
                switch (naviTypeName) {
                    case "步行":
                        naviType = 0;
                        break;
                    case "骑行":
                        naviType = 1;
                        break;
                    case "驾车":
                        naviType = 2;
                        break;
                }
                if (isNavi) {
                    isNavi = false;
                    aMapNavi.stopNavi();
                    startNavi_button.setSelected(false);
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        startNavi_button = (ImageButton) findViewById(R.id.start_navi_btn);
        startNavi_button.setOnClickListener(this);

        nextTurnTipBiew = (NextTurnTipView) findViewById(R.id.my_nextturntipview);
        aMapNavView.setLazyNextTurnTipView(nextTurnTipBiew);
        direction_textView = (TextView) findViewById(R.id.direction_tv);
        pathRetainDistance_textView = (TextView) findViewById(R.id.path_retain_distance_tv);
        currentRoadName_textView = (TextView) findViewById(R.id.current_road_name_tv);
        totalPathRetainDistance_textView = (TextView) findViewById(R.id.total_path_retain_distance_tv);
        pathRetainTime_textView = (TextView) findViewById(R.id.path_retain_time_tv);
        //获得汽车信息
        Bundle bundle = getIntent().getExtras();
        latitude = bundle.getDouble(Constant.TerminalInfo.terminalLatitude);
        longitude = bundle.getDouble(Constant.TerminalInfo.terminalLongitude);
        options = aMapNavView.getViewOptions();
        options.setLayoutVisible(false);
        mZoomInIntersectionView = (ZoomInIntersectionView) findViewById(R.id.my_zoom_in_intersectionview);
        aMapNavView.setLazyZoomInIntersectionView(mZoomInIntersectionView);
        //实时路况button
        traffic_button = (ImageButton) findViewById(R.id.my_traffic_button);
        traffic_button.setOnClickListener(this);
        traffic_button.setSelected(isOpenTraffic);

        aMapNavView.setTrafficLine(isOpenTraffic);
        aMapNavView.setViewOptions(options);

        naviVoice_button = (FloatingActionButton) findViewById(R.id.navi_voice_btn);
        naviVoice_button.setOnClickListener(this);
        //初始化SpeechSynthesizer,第二个参数：本地合成传InitListener
        mTts = SpeechSynthesizer.createSynthesizer(this, null);
        //合成参数设置
        mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoyan");//设置发音人
        mTts.setParameter(SpeechConstant.SPEED, "50");//设置语速
        mTts.setParameter(SpeechConstant.VOLUME, "80");//设置音量，范围0-100
    }

    //定位当前位置,并将中心移到当前位置
    private void initPersonal() {
        GaoDeMapUtil.getLocation(new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {
                personalNaviLatLng = new NaviLatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                //判断选择的导航路径方式
                switch (naviType) {
                    case 0:
                        //设置步行寻车导航路径
                        aMapNavi.calculateWalkRoute(personalNaviLatLng, new NaviLatLng(latitude, longitude));
                        //设置导航图标
                        options.setCarBitmap(BitmapFactory.decodeResource(GDCarNavigationFindActivity.this.getResources(), R.mipmap.ico_navi_personal));
                        break;
                    case 1:
                        //设置骑行寻车导航路径
                        aMapNavi.calculateRideRoute(personalNaviLatLng, new NaviLatLng(latitude, longitude));
                        //设置导航图标
                        options.setCarBitmap(BitmapFactory.decodeResource(GDCarNavigationFindActivity.this.getResources(), R.mipmap.motorcycle_left_online));
                        break;
                    case 2:
                        //设置导航图标
                        options.setCarBitmap(BitmapFactory.decodeResource(GDCarNavigationFindActivity.this.getResources(), R.drawable.fragment_car_monitor_car_online));
                        //设置驾车寻车导航路径
                        /**
                         * 方法:
                         *   int strategy=mAMapNavi.strategyConvert(congestion, avoidhightspeed, cost, hightspeed, multipleroute);
                         * 参数:
                         * @congestion 躲避拥堵
                         * @avoidhightspeed 不走高速
                         * @cost 避免收费
                         * @hightspeed 高速优先
                         * @multipleroute 多路径
                         *
                         * 说明:
                         *      以上参数都是boolean类型，其中multipleroute参数表示是否多条路线，如果为true则此策略会算出多条路线。
                         * 注意:
                         *      不走高速与高速优先不能同时为true
                         *      高速优先与避免收费不能同时为true
                         */
                        int strategy = 0;
                        try {
                            strategy = aMapNavi.strategyConvert(true, false, false, false, false);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        List<NaviLatLng> startList = new ArrayList<>();
                        startList.add(personalNaviLatLng);
                        List<NaviLatLng> endList = new ArrayList<>();
                        endList.add(new NaviLatLng(latitude, longitude));
                        aMapNavi.calculateDriveRoute(startList, endList, null, strategy);
                        break;
                }
                aMapNavView.setViewOptions(options);
            }
        });
    }

    /**
     * 导航地图设置
     */
    private void initNavMap() {
        //获取AMapNavi实例
        aMapNavi = AMapNavi.getInstance(getApplicationContext());
        //设置模拟导航的步行速度
//        aMapNavi.setEmulatorNaviSpeed(100);
        //添加监听回调，用于处理算路成功
        aMapNavi.addAMapNaviListener(new AMapNaviListener() {
            @Override
            public void onInitNaviFailure() {
                //导航创建失败时的回调函数。
                L.i(TAG, "onInitNaviFailure: ");
            }

            @Override
            public void onInitNaviSuccess() {
                //导航创建成功时的回调函数。
                L.i(TAG, "onInitNaviSuccess: ");
            }

            @Override
            public void onStartNavi(int i) {
                L.i(TAG, "onStartNavi: ");
            }

            @Override
            public void onTrafficStatusUpdate() {
                //当前方路况光柱信息有更新时回调函数。
                L.i(TAG, "onTrafficStatusUpdate: ");
            }

            @Override
            public void onLocationChange(AMapNaviLocation aMapNaviLocation) {
                //当GPS位置有更新时的回调函数。
                L.i(TAG, "onLocationChange: ");
            }

            @Override
            public void onGetNavigationText(int i, String s) {
                //导航播报信息回调函数。
                //开始合成语音
                if (isOpenVoice)
                    mTts.startSpeaking(s, mSynListener);
            }

            @Override
            public void onEndEmulatorNavi() {
                //模拟导航停止后回调函数。
                L.i(TAG, "onEndEmulatorNavi: ");
            }

            @Override
            public void onArriveDestination() {
                //到达目的地后回调函数。
                L.i(TAG, "onArriveDestination: ");
                Toast.makeText(GDCarNavigationFindActivity.this, R.string.toast_navi_over, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onArriveDestination(NaviStaticInfo naviStaticInfo) {
                L.i(TAG, "onArriveDestination: ");
            }

            @Override
            public void onArriveDestination(AMapNaviStaticInfo aMapNaviStaticInfo) {
                L.i(TAG, "onArriveDestination: ");
            }

            @Override
            public void onCalculateRouteSuccess() {
                //多路线算路成功回调,显示路径或开始导航
                aMapNavi.startNavi(NaviType.GPS);
                //模拟导航
//                aMapNavi.startNavi(NaviType.EMULATOR);
            }

            @Override
            public void onCalculateRouteFailure(int i) {
                //步行或者驾车路径规划失败后的回调函数。
                L.i(TAG, "onCalculateRouteFailure: ");
            }

            @Override
            public void onReCalculateRouteForYaw() {
                //步行或驾车导航时,出现偏航后需要重新计算路径的回调函数。
                L.i(TAG, "onReCalculateRouteForYaw: ");
            }

            @Override
            public void onReCalculateRouteForTrafficJam() {
                //驾车导航时，如果前方遇到拥堵时需要重新计算路径的回调。
                L.i(TAG, "onReCalculateRouteForTrafficJam: ");
            }

            @Override
            public void onArrivedWayPoint(int i) {
                //驾车路径导航到达某个途经点的回调函数。
                L.i(TAG, "onArrivedWayPoint: ");
            }

            @Override
            public void onGpsOpenStatus(boolean b) {
                //用户手机GPS设置是否开启的回调函数。
                L.i(TAG, "onGpsOpenStatus: ");
            }

            @Override
            public void onNaviInfoUpdated(AMapNaviInfo aMapNaviInfo) {
            }

            @Override
            public void onNaviInfoUpdate(NaviInfo naviInfo) {
                //导航引导信息回调 naviinfo 是导航信息类。
                direction_textView.setText(directionTransformation(naviInfo.getDirection()));
                pathRetainDistance_textView.setText(distanceTransformation(naviInfo.getCurStepRetainDistance()));
                currentRoadName_textView.setText(naviInfo.getCurrentRoadName());
                totalPathRetainDistance_textView.setText("剩余距离：" + "\n" + distanceTransformation(naviInfo.getPathRetainDistance()));
                pathRetainTime_textView.setText("剩余时间：" + "\n" + TimeUtils.timeTransformation(naviInfo.getPathRetainTime()));
                naviInfo.getIconType();
            }

            @Override
            public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo aMapNaviTrafficFacilityInfo) {
                L.i(TAG, "OnUpdateTrafficFacility: ");
            }

            @Override
            public void OnUpdateTrafficFacility(TrafficFacilityInfo trafficFacilityInfo) {
                L.i(TAG, "OnUpdateTrafficFacility: ");
            }

            @Override
            public void showCross(AMapNaviCross aMapNaviCross) {
                //显示路口放大图回调。
                mZoomInIntersectionView.setImageBitmap(aMapNaviCross.getBitmap());
                mZoomInIntersectionView.setVisibility(View.VISIBLE);
            }

            @Override
            public void hideCross() {
                //关闭路口放大图回调。
                mZoomInIntersectionView.setVisibility(View.INVISIBLE);
            }

            @Override
            public void showLaneInfo(AMapLaneInfo[] aMapLaneInfos, byte[] bytes, byte[] bytes1) {
                //显示道路信息回调。
                L.i(TAG, "showLaneInfo: ");
            }

            @Override
            public void hideLaneInfo() {
                //关闭道路信息回调。
                L.i(TAG, "hideLaneInfo: ");
            }

            @Override
            public void onCalculateMultipleRoutesSuccess(int[] ints) {
                L.i(TAG, "onCalculateMultipleRoutesSuccess: ");
            }

            @Override
            public void notifyParallelRoad(int i) {
                //通知当前是否显示平行路切换
                L.i(TAG, "notifyParallelRoad: ");
            }

            @Override
            public void OnUpdateTrafficFacility(AMapNaviTrafficFacilityInfo[] aMapNaviTrafficFacilityInfos) {
                L.i(TAG, "OnUpdateTrafficFacility: ");
            }

            @Override
            public void updateAimlessModeStatistics(AimLessModeStat aimLessModeStat) {
                //巡航模式（无路线规划）下，统计信息更新回调 连续5个点大于15km/h后开始回调
                L.i(TAG, "updateAimlessModeStatistics: ");
            }

            @Override
            public void updateAimlessModeCongestionInfo(AimLessModeCongestionInfo aimLessModeCongestionInfo) {
                //巡航模式（无路线规划）下，统计信息更新回调 当拥堵长度大于500米且拥堵时间大于5分钟时回调
                L.i(TAG, "updateAimlessModeCongestionInfo: ");
            }
        });
    }

    //语音合成监听器
    private SynthesizerListener mSynListener = new SynthesizerListener() {
        //开始播放
        @Override
        public void onSpeakBegin() {

        }

        //缓冲进度回调
        //i为缓冲进度0-100，i1为缓存音频在文本中开始位置，i2为缓冲音频在文本中结束位置,info为附加信息
        @Override
        public void onBufferProgress(int i, int i1, int i2, String s) {

        }

        //暂停播放
        @Override
        public void onSpeakPaused() {

        }

        //恢复播放回调接口
        @Override
        public void onSpeakResumed() {

        }

        //播放进度回调
        //i为播放进度0-100，i1为播放音频在文本中开始位置，i2为播放音频在文本中结束位置
        @Override
        public void onSpeakProgress(int i, int i1, int i2) {

        }

        //会话结束回调接口，没有错误时,speechError为null
        @Override
        public void onCompleted(SpeechError speechError) {

        }

        //会话事件回调接口
        @Override
        public void onEvent(int i, int i1, int i2, Bundle bundle) {

        }
    };

    /**
     * 距离数据转换
     *
     * @param distance
     * @return
     */
    private String distanceTransformation(int distance) {
        String distanceString = "";
        if (distance < 0 || distance == 0) {
        } else if (distance < 1000) {
            distanceString = String.valueOf(distance) + "M";
        } else if (distance > 1000) {
            float a = (float) distance / 1000;
            float b = (float) (Math.round(a * 100)) / 100;
            distanceString = String.valueOf(b) + "Km";
        }
        return distanceString;
    }

    /**
     * 方向转换
     *
     * @param direction
     * @return
     */
    private String directionTransformation(float direction) {
        String directionString = "";
        if (direction == 0) {
            directionString = "北";
        } else if (direction > 0 && direction <= 45) {
            directionString = "北偏东" + String.valueOf(direction) + "°";
        } else if (direction > 45 && direction < 90) {
            directionString = "东偏北" + String.valueOf(direction - 45) + "°";
        } else if (direction == 90) {
            directionString = "东";
        } else if (direction > 90 && direction <= 135) {
            directionString = "东偏南" + String.valueOf(direction - 90) + "°";
        } else if (direction > 135 && direction < 180) {
            directionString = "南偏东" + String.valueOf(direction - 135) + "°";
        } else if (direction == 180) {
            directionString = "南";
        } else if (direction > 180 && direction <= 225) {
            directionString = "南偏西" + String.valueOf(direction - 180) + "°";
        } else if (direction > 225 && direction < 270) {
            directionString = "南偏西" + String.valueOf(direction - 225) + "°";
        } else if (direction == 270) {
            directionString = "西";
        } else if (direction > 270 && direction <= 315) {
            directionString = "西偏北" + String.valueOf(direction - 270) + "°";
        } else if (direction > 315 && direction < 360) {
            directionString = "北偏西" + String.valueOf(direction - 225) + "°";
        }
        return directionString;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.back_btn:
                if (isNavi) {
                    isNavi = false;
                    startNavi_button.setSelected(false);
                    aMapNavi.stopNavi();
                }
                finish();
                break;
            case R.id.start_navi_btn:
                isNavi = !isNavi;
                startNavi_button.setSelected(isNavi);
                //开始导航
                if (isNavi) {
                    initPersonal();
                } else {
                    aMapNavi.pauseNavi();
                }
                break;
            case R.id.navi_voice_btn:
                isOpenVoice = !isOpenVoice;
                naviVoice_button.setSelected(isOpenVoice);
                if (!isOpenVoice) {
                    mTts.pauseSpeaking();
                }
                break;
            case R.id.my_traffic_button:
                isOpenTraffic = !isOpenTraffic;
                traffic_button.setSelected(isOpenTraffic);
                aMapNavView.setTrafficLine(isOpenTraffic);
                break;
        }

    }

    @Override
    protected void onResume() {
        super.onResume();
        aMapNavView.onResume();
        aMapNavi.resumeNavi();
    }

    @Override
    protected void onPause() {
        super.onPause();
        aMapNavView.onPause();
        aMapNavi.pauseNavi();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        aMapNavView.onDestroy();
        aMapNavi.destroy();
    }

    class CarNaviTypeAdapter extends BaseAdapter {
        private List<Map<String, Object>> typeList;

        CarNaviTypeAdapter(List<Map<String, Object>> typeList) {
            this.typeList = typeList;
        }


        @Override
        public int getCount() {
            return typeList.size();
        }

        @Override
        public Map<String, Object> getItem(int i) {
            return typeList.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(final int i, View view, ViewGroup viewGroup) {
            final ViewHolder viewHolder;
            if (view == null) {
                viewHolder = new ViewHolder();
                view = getLayoutInflater().inflate(R.layout.item_navi_type, null);
                viewHolder.naviType_imageView = (ImageView) view.findViewById(R.id.navi_type_img);
                viewHolder.naviType_textView = (TextView) view.findViewById(R.id.navi_type_tv);
                view.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) view.getTag();
            }
            // 设置导航方式图标
            viewHolder.naviType_imageView.setImageResource((Integer) typeList.get(i).get("typeImg"));
            // 设置导航方式名称
            String naviTypeName = getResources().getString((Integer) typeList.get(i).get("typeName"));
            viewHolder.naviType_textView.setText(naviTypeName);
            return view;
        }

    }

    class ViewHolder {
        ImageView naviType_imageView;
        TextView naviType_textView;
    }
}
